package name.weily.liba.tools

import java.util.concurrent.Future
import java.util.concurrent.LinkedBlockingQueue
import java.util.concurrent.ThreadPoolExecutor
import java.util.concurrent.TimeUnit

class AppThreadPool {
    companion object {
        private var appThreadPool: AppThreadPool? = null

        fun getInstance() : AppThreadPool {
            return appThreadPool ?: synchronized(AppThreadPool::class.java) {
                return appThreadPool ?: AppThreadPool().apply { appThreadPool = this }
            }
        }
    }

    enum class PoolSize {
        Single, Middle, Large
    }

    private val singleService by lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
        logd(tag = "AppThreadPool", message = "create singleService pool")
        ThreadPoolExecutor(1, 1, 0, TimeUnit.SECONDS,
            LinkedBlockingQueue<Runnable>())
    }

    private val middleService by lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
        logd(tag = "AppThreadPool", message = "create middleService pool")
        ThreadPoolExecutor(3, 5, 10, TimeUnit.SECONDS,
            LinkedBlockingQueue<Runnable>())
    }

    private val largeService by lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
        logd(tag = "AppThreadPool", message = "create largeService pool")
        ThreadPoolExecutor(3, 30, 10, TimeUnit.SECONDS,
            LinkedBlockingQueue<Runnable>())
    }

    fun post(which: PoolSize = PoolSize.Middle, task: () -> Unit) {
        when (which) {
            PoolSize.Single -> singleService.execute(task)
            PoolSize.Middle -> middleService.execute(task)
            PoolSize.Large -> largeService.execute(task)
        }
    }

    fun submit(which: PoolSize = PoolSize.Middle, task: () -> Unit) : Future<*> {
        return when (which) {
            PoolSize.Single -> singleService.submit(task)
            PoolSize.Middle -> middleService.submit(task)
            PoolSize.Large -> largeService.submit(task)
        }
    }
}